import 'dart:convert';

import 'package:uuid/uuid.dart';

import '../const_value.dart';
import 'file_model.dart';

class Message {
  static const tableName = "im_message";

  static const createTableSQL = """
      CREATE TABLE $tableName (
        mid CHAR(32) PRIMARY KEY NOT NULL,
        fromId CHAR(32) NOT NULL,
        toId CHAR(32) NOT NULL,
        body VARCHAR($messageLen) NOT NULL,
        height INT default 0,
        width INT default 0,
        time INT NOT NULL,
        type SMALLINT default 0,
        status SMALLINT default 2,
        readFlag SMALLINT default 0,
        combKey CHAR(64) NOT NULL
      )""";

  static const columnSQL =
      "mid, fromId, toId, body, height, width, time, type, status, readFlag, combKey";

  static const insertSQL = """
  insert into $tableName ($columnSQL) values (?,?,?,?,?,?,?,?,?,?,?)
  """;

  static const querySQL = """
  select $columnSQL from $tableName where combKey = ? and type in (0, 1, 2, 3) order by time desc limit ?,? 
  """;

  static const queryAddFriendMsgSQL = """
  select $columnSQL from $tableName where type = 4 order by time desc limit ?,?
  """;

  static const countAddFriendMsgSQL = """
  select count(*) count from $tableName where type = 4 and type = 0
  """;

  static const queryById = """
  select $columnSQL from $tableName where mid = ?
  """;

  static const updateImgUrl = """
  update $tableName set body = ? where mid = ?
  """;

  List<dynamic> getInsertArguments() {
    return [
      this.mid,
      this.fromId,
      this.toId,
      this.body,
      this.height,
      this.width,
      this.time.millisecondsSinceEpoch,
      this.type,
      this.status,
      this.readFlag,
      this.combKey
    ];
  }

  String mid;

  String fromId;
  String toId;
  String body;

  int height;
  int width;

  DateTime time; // 精确到秒

  /// 消息类型
  /// -2 消息回执
  /// -1 心跳 消息
  /// 0 文本
  /// 1 语音
  /// 2 图片
  /// 3 文件
  /// 4 加好友
  int type;

  /// 消息状态
  /// -1 发送失败
  /// 0 已发送，对方暂未收到
  /// 1 已发送，对方且收到
  /// 2 发送中 ...
  int status;

  /// 已读未读标志
  /// 0 未读
  /// 1 已读
  /// 2 已同意
  /// 3 已拒绝
  int readFlag;

  String combKey; // 组合key  登录人+聊天人

  FileModel fileModel; // type = 2/3 有值

  Message(
      {this.mid,
      this.fromId,
      this.toId,
      this.body,
      this.height,
      this.width,
      this.time,
      this.type = 0,
      this.status = 2,
      this.readFlag = 0,
      this.combKey}) {
    this.mid = mid == null ? Uuid().v4().replaceAll("-", "") : mid;
    this.time = time == null ? DateTime.now() : time;
    this.combKey = combKey == null ? "" : combKey;
  }

  bool fileType() {
    return type == 2 || type == 3;
  }

  String toJson() {
    final data = {
      "mid": mid,
      "fromId": fromId,
      "toId": toId,
      "body": body,
      "time": time.millisecondsSinceEpoch,
      "type": type,
      "readFlag" : readFlag,
    };
    if (2 == type) {
      data["width"] = width;
      data["height"] = height;
    }
    return json.encode(data);
  }

  static Message fromJson(Map<String, dynamic> map) {
    int time = map["time"];
    return Message(
        mid: map["mid"],
        fromId: map["fromId"],
        toId: map["toId"],
        body: map["body"],
        height: map["height"],
        width: map["width"],
        time: DateTime.fromMillisecondsSinceEpoch(time),
        type: map["type"],
        status: map["status"],
        readFlag: map["readFlag"],
        combKey: map["combKey"]);
  }

  static List<Message> fromJsonList(List<Map<String, dynamic>> list) {
    return list.map((m) => fromJson(m)).toList();
  }

  @override
  String toString() {
    return 'Message{mid: $mid, fromId: $fromId, toId: $toId, body: $body, height: $height, width: $width, time: $time,'
        ' type: ${typeMap[type]}, status: ${statusMap[status]}, readFlag: ${readFlagMap[readFlag]} combKey: ${combKey}, friendModel: ${fileModel}';
  }

  Message convertToImageMsg() {
    return Message(
        mid: this.mid,
        fromId: this.fromId,
        toId: this.toId,
        time: this.time,
        type: this.type,
        status: this.status,
        readFlag: this.readFlag,
        combKey: this.combKey,
        body: this.fileModel?.url,
        width: this.fileModel?.width,
        height: this.fileModel?.height);
  }
}

const typeMap = {-2: "消息回执", -1: "心跳", 0: "文本", 1: "语音", 2: "图片", 3: "文件", 4: "添加"};

const statusMap = {-1: "发送失败", 0: "已发送，对方暂未收到", 1: "已发送，对方且收到", 2: "发送中"};

const readFlagMap = {0: "未读", 1: "已读", 2: "已同意", 3: "已拒绝"};
